package org.jeecg.common.util;

import org.springframework.format.Formatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

public class DateFormatter implements Formatter<Date> {
    private static final Map<Pattern, SimpleDateFormat> FORMAT_MAP;
    private static final Pattern EMPTY_STR_PATTERN = Pattern.compile("^\\s*$");
    private static final SimpleDateFormat DEFAULT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    static {
        Map<Pattern, SimpleDateFormat> patternMap = new HashMap<>(4);
        patternMap.put(Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$"), new SimpleDateFormat("yyyy-MM-dd"));
        patternMap.put(Pattern.compile("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        patternMap.put(Pattern.compile("^\\d{4}/\\d{2}/\\d{2}$"), new SimpleDateFormat("yyyy/MM/dd"));
        patternMap.put(Pattern.compile("^\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}$"), new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));

        FORMAT_MAP = Collections.unmodifiableMap(patternMap);
    }

    /**
     * Parse a text String to produce a T.
     *
     * @param text   the text string
     * @param locale the current user locale
     * @return an instance of T
     * @throws ParseException           when a parse exception occurs in a java.text parsing library
     * @throws IllegalArgumentException when a parse exception occurs
     */
    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        if (text == null || EMPTY_STR_PATTERN.matcher(text).matches()) {
            return null;
        } else {
            Iterator<Map.Entry<Pattern, SimpleDateFormat>> iter = FORMAT_MAP.entrySet().iterator();
            Map.Entry<Pattern, SimpleDateFormat> entry = null;

            Date date = null;
            Pattern pattern = null;
            SimpleDateFormat dateFormat = null;
            while (iter.hasNext()) {
                entry = iter.next();

                pattern = entry.getKey();
                dateFormat = entry.getValue();

                if (pattern.matcher(text).matches()) {
                    date = dateFormat.parse(text);
                }
            }

            return date;
        }
    }

    /**
     * Print the object of type T for display.
     *
     * @param object the instance to print
     * @param locale the current user locale
     * @return the printed text string
     */
    @Override
    public String print(Date object, Locale locale) {
        if (object == null) {
            return null;
        } else {
            return DEFAULT_FORMAT.format(object);
        }
    }
}
